package chap_02_CAS.step_03_AdderAccumulator;

import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.LongBinaryOperator;

/**
 * @Description LongAdder、LongAccumulator 简单 API 学习
 * @Author shihan
 * @Date 2022/10/30 15:50
 * @Version 1.0
 */
public class LongAdderAccumulator_01_API {

    /**
     * 【相同点】：
     * 1、获取最终结果（求和/运算结果）时，并不是原子操作的，会与实际的数据有一丢丢偏差；
     * 2、适用于并发量非常大的数据处理场景；
     * PS：因为并发量很大，并且能容忍轻微的数据不一致性，所以这一套API的效率很高；
     * 【不同点】
     * 1、LongAdder：
     * ---初始值只能是 0；
     * ---只能进行加、减运算动作；
     * 2、LongAccumulator：
     * ---可以自己指定初始值；
     * ---可以自己指定运算规则；
     *
     * @param args
     */
    public static void main(String[] args) {
        LongAdder longAdder = new LongAdder();
        longAdder.increment();
        longAdder.increment();
        longAdder.increment();
        System.out.println(longAdder.sum());

        //==============================================================================
        /**
         * 参数一：运算规则（Functional函数式接口，可以匿名实现，也可以用 lambda 表达式）
         * 参数二：初始化值
         */
        LongAccumulator longAccumulator = new LongAccumulator(new LongBinaryOperator() {

            /**
             *
             * @param left 初始值/上一次运算后的结果值
             * @param right 当前操作数的值，和 left 左侧的 初始值/上一次运算后的结果值 进行对应的运算操作
             * @return
             */
            @Override
            public long applyAsLong(long left, long right) {
                return left * right;
            }
        }, 1);

        longAccumulator.accumulate(2);  // 1*2=2
        longAccumulator.accumulate(3);  // 2*3=6
        longAccumulator.accumulate(4);  // 6*4=24
        System.out.println(longAccumulator.get());

    }

}
